package com.eastfair.builder.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
//import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.eastfair.boot.service.SuperServiceImpl;
import com.eastfair.builder.dao.ReportDrawingMapper;
import com.eastfair.builder.dto.ReportDrawingDTO;
import com.eastfair.builder.entity.ReportDrawing;
import com.eastfair.builder.entity.ReportSpace;
import com.eastfair.builder.enumeration.ReportSpaceReportSpaceStatusEnum;
import com.eastfair.builder.exceptioncode.BuilderExceptionCode;
import com.eastfair.builder.service.*;
import com.eastfair.builder.vo.ReportDrawingCategoryVO;
import com.eastfair.builder.vo.ReportDrawingVO;
import com.eastfair.builder.vo.ReportSiteVO;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.exception.BizException;
import com.eastfair.home.dto.ReportDrawingAuditDTO;
import com.eastfair.home.dto.ReportDrawingCategoryAuditDTO;
import com.eastfair.venueservice.consts.CommonConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 业务实现类
 * 报馆图纸
 * </p>
 *
 * @author dq
 * @date 2022-08-06
 */
@Slf4j
@Service
//@DS("#thread.tenant")
public class ReportDrawingServiceImpl extends SuperServiceImpl<ReportDrawingMapper, ReportDrawing> implements ReportDrawingService {

    @Resource
    private ReportDrawingMapper reportDrawingMapper;

    @Resource
    private ReportSpaceService reportSpaceService;

    @Resource
    private ReportSiteService reportSiteService;

    @Resource
    private BuilderDrawingService builderDrawingService;

    @Resource
    private BuilderReportDrawingCategoryAuditService builderReportDrawingCategoryAuditService;

    /**
     * 处理逻辑删除相关处理
     *
     * @param modelList 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerRemoveByIdsOfLogic(Collection<ReportDrawing> modelList) {
        modelList.forEach(s -> s.setIsDeleted(BusinessConstant.YES));
        return R.successDef();
    }

    @Override
    protected R<Boolean> handlerSave(ReportDrawing model) {
        model.setProjectId(ContextUtil.getProjectId());
        model.setSubsystemId(ContextUtil.getSubSystemId());
        return R.successDef();
    }

    @Override
    public List<ReportDrawingCategoryVO> listCategoryVOByReportSpaceId(Long reportSpaceId) {
        log.info("listDrawingCategoriesByReportSpaceId - 查询图纸分类列表, reportSpaceId={}", reportSpaceId);
        ReportSpace reportSpace = reportSpaceService.getById(reportSpaceId);
        if (reportSpace == null) {
            throw BizException.wrap(BuilderExceptionCode.REPORT_SPACE_NOT_EXIST);
        }
        ReportSiteVO reportSite = reportSiteService.getVOByReportSpaceId(reportSpaceId);
        if (reportSite == null) {
            throw BizException.wrap(BuilderExceptionCode.REPORT_SITE_NOT_EXIST.getCode(), "请先完善展位基本信息，指定单双层与是否吊点");
        }
        // 如果报馆记录为已提交或审核通过，则不可编辑，查询原来提交的分类
        if (ReportSpaceReportSpaceStatusEnum.APPROVED.eq(reportSpace.getReportSpaceStatus())
                || ReportSpaceReportSpaceStatusEnum.SUBMIT.eq(reportSpace.getReportSpaceStatus())) {
            return builderReportDrawingCategoryAuditService.listReportDrawingCategoryVOByReportSpaceId(reportSpaceId);
        }
        // 如果报馆记录可编辑，则查询目前主场配置的图纸分类
        return listCategoryVOWhenNotApprovedByExhibitionId(reportSpace.getExhibitionId(), reportSpaceId, reportSite.getIsDouble(), reportSite.getIsPoint());
    }

    @Override
    public List<ReportDrawingCategoryVO> listCategoryVOWhenNotApprovedByExhibitionId(Long exhibitionId, Long reportSpaceId, Integer isDouble, Integer isPoint) {
        // 查询当前设置的图纸分类
        List<ReportDrawingCategoryVO> nowReportDrawingCategoryList = builderDrawingService.
                listReportDrawingCategoryVOsByExhibitionId(exhibitionId, isDouble, isPoint);
        if (nowReportDrawingCategoryList == null || nowReportDrawingCategoryList.isEmpty()) {
            return Collections.emptyList();
        }
        // 查询已审核的图纸类型
        List<ReportDrawingCategoryVO> hasAuditReportDrawingCategoryList
                = builderReportDrawingCategoryAuditService.listReportDrawingCategoryVOByReportSpaceId(reportSpaceId);
        if (hasAuditReportDrawingCategoryList == null || hasAuditReportDrawingCategoryList.isEmpty()) {
            return nowReportDrawingCategoryList;
        }
        Map<Long, ReportDrawingCategoryVO> auditMap = new HashMap<>(16);
        hasAuditReportDrawingCategoryList.forEach(reportDrawingCategoryVO -> auditMap.put(reportDrawingCategoryVO.getDrawingCategoryId(), reportDrawingCategoryVO));
        // 将已审核的图纸分类的审核信息封装到当前设置的图纸分类中
        for (ReportDrawingCategoryVO nowReportDrawingCategory : nowReportDrawingCategoryList) {
            ReportDrawingCategoryVO hasAuditReportDrawingCategory = auditMap.get(nowReportDrawingCategory.getDrawingCategoryId());
            if (hasAuditReportDrawingCategory != null) {
                BeanUtil.copyProperties(hasAuditReportDrawingCategory, nowReportDrawingCategory);
            }
        }
        return nowReportDrawingCategoryList;
    }

    @Override
    public boolean getNeedVenueAudit(Long reportSpaceId, Integer isDouble, Integer isPoint) {
        ReportSpace reportSpace = reportSpaceService.getById(reportSpaceId);
        if (reportSpace == null) {
            throw BizException.wrap(BuilderExceptionCode.REPORT_SPACE_NOT_EXIST);
        }
        List<ReportDrawingCategoryVO> reportDrawingCategoryList = listCategoryVOWhenNotApprovedByExhibitionId(reportSpace.getExhibitionId(), reportSpaceId, isDouble, isPoint);
        if (reportDrawingCategoryList == null || reportDrawingCategoryList.isEmpty()) {
            return false;
        }
        // 如果当前提交的图纸有需要吊点的图纸，则报馆需要场馆审核
        for (ReportDrawingCategoryVO reportDrawingCategoryVO : reportDrawingCategoryList) {
            if (reportDrawingCategoryVO.getIsPoint() != null && reportDrawingCategoryVO.getIsPoint() == BusinessConstant.YES) {
                return true;
            }
        }
        return false;
    }

    @Override
    public List<ReportDrawingVO> listVOByReportSpaceId(Long reportSpaceId, Long drawingId) {
        log.info("listReportDrawingVOsByReportSpaceId - 报馆ID，图纸分类ID查询报馆图纸列表, reportSpaceId={}, drawingId={}",
                reportSpaceId, drawingId);
        ReportDrawingDTO query = new ReportDrawingDTO();
        query.setReportSpaceId(reportSpaceId);
        query.setDrawingCategoryId(drawingId);
        List<ReportDrawing> list = listReportDrawings(query);
        if (list == null || list.isEmpty()) {
            return Collections.emptyList();
        }
        return list
                .stream()
                .map(reportDrawing -> BeanUtil.toBean(reportDrawing, ReportDrawingVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public List<ReportDrawing> listByReportSpaceId(Long reportSpaceId) {
        log.info("listReportDrawingsByReportSpaceId - 报馆ID查询报馆图纸列表, reportSpaceId={}", reportSpaceId);
        ReportDrawingDTO query = new ReportDrawingDTO();
        query.setReportSpaceId(reportSpaceId);
        return listReportDrawings(query);
    }

    @Override
    public List<ReportDrawing> listReportDrawings(ReportDrawingDTO query) {
        log.info("listReportDrawings - 查询报馆图纸列表, query={}", query);
        QueryWrapper<ReportDrawing> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .lambda()
                .eq(ReportDrawing::getIsDeleted, BusinessConstant.DELETE_NO)
                .eq(query.getReportSpaceId() != null, ReportDrawing::getReportSpaceId, query.getReportSpaceId())
                .eq(query.getDrawingCategoryId() != null, ReportDrawing::getDrawingCategoryId, query.getDrawingCategoryId())
                .in(query.getImageUrlList() != null && !query.getImageUrlList().isEmpty(), ReportDrawing::getImageUrl, query.getImageUrlList())
        ;
        return list(queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveReportDrawings(ReportDrawingDTO reportDrawingDTO) {
        log.info("saveReportDrawings - 保存图片, reportDrawingDTO={}", reportDrawingDTO);
        ReportDrawing reportDrawing = BeanUtil.toBean(reportDrawingDTO, ReportDrawing.class);
        return save(reportDrawing);
    }

    @Override
    public List<ReportDrawingCategoryAuditDTO> createAuditListByReportSpaceId(Long reportSpaceId) {
        // 查询图纸分类列表
        List<ReportDrawingCategoryVO> reportDrawingCategoryList = listCategoryVOByReportSpaceId(reportSpaceId);
        if (reportDrawingCategoryList == null || reportDrawingCategoryList.isEmpty()) {
            throw BizException.wrap(BuilderExceptionCode.HOME_DRAWING_QUERY_ERROR.getCode(), "图纸分类未指定，请联系主场设置图纸分类");
        }
        // 查询全部图纸
        List<ReportDrawing> reportDrawingList = listByReportSpaceId(reportSpaceId);
        if (reportDrawingList == null || reportDrawingList.isEmpty()) {
            throw BizException.wrap(BuilderExceptionCode.REPORT_DRAWING_NOT_EXIST.getCode(), "无法提交，请上传图纸");
        }
        // 图纸类型封装对应的图纸
        List<ReportDrawingCategoryAuditDTO> reportDrawingCategoryAuditList = new ArrayList<>();
        for (ReportDrawingCategoryVO reportDrawingCategoryVO : reportDrawingCategoryList) {
            CopyOptions copyOptions = CopyOptions
                    .create()
                    .setIgnoreProperties(CommonConstants.COMMON_IGNORE_PROPERTIES);
            ReportDrawingCategoryAuditDTO reportDrawingCategoryAuditDTO = BeanUtil.toBean(reportDrawingCategoryVO, ReportDrawingCategoryAuditDTO.class, copyOptions);
            List<ReportDrawingAuditDTO> reportDrawingAuditDTOList = new ArrayList<>();
            for (ReportDrawing reportDrawing : reportDrawingList) {
                if (reportDrawing.getDrawingCategoryId().equals(reportDrawingCategoryVO.getDrawingCategoryId())) {
                    ReportDrawingAuditDTO reportDrawingAuditDTO = BeanUtil.toBean(reportDrawing, ReportDrawingAuditDTO.class, copyOptions);
                    reportDrawingAuditDTOList.add(reportDrawingAuditDTO);
                }
            }
            // 图纸类型下必须有图纸上传
            if (reportDrawingAuditDTOList.isEmpty()) {
                throw BizException.wrap(BuilderExceptionCode.REPORT_DRAWING_NOT_EXIST.getCode(), "无法提交，所有图纸类型必须上传图纸");
            }
            reportDrawingCategoryAuditDTO.setReportSpaceId(reportSpaceId);
            reportDrawingCategoryAuditDTO.setReportDrawingAuditList(reportDrawingAuditDTOList);
            reportDrawingCategoryAuditList.add(reportDrawingCategoryAuditDTO);
        }
        return reportDrawingCategoryAuditList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeByReportSpaceId(Long reportSpaceId) {
        List<ReportDrawing> reportDrawingList = listByReportSpaceId(reportSpaceId);
        if (reportDrawingList == null || reportDrawingList.isEmpty()) {
            return false;
        }
        return removeByIdsOfLogic(reportDrawingList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeByImageUrl(List<String> list) {
        ReportDrawingDTO query = new ReportDrawingDTO();
        query.setImageUrlList(list);
        List<ReportDrawing> reportDrawings = listReportDrawings(query);
        if (reportDrawings == null || reportDrawings.isEmpty()) {
            return false;
        }
        return removeByIdsOfLogic(reportDrawings);
    }
}
